<template>
  <n-tree
    block-line
    draggable
    :data="dataRef"
    :checked-keys="checkedKeysRef"
    :expanded-keys="expandedKeysRef"
    @drop="handleDrop"
    @update:expanded-keys="handleExpandedKeysChange"
    style="font-size: 18px; margin-left: -3px;"
    :check-strictly="true"
    :render-switcher-icon="renderSwitcherIconWithExpaned"
    :override-default-node-click-behavior="override"
    :on-load="handleLoad"
    :render-suffix="renderSuffix"
    expand-on-click
    class="right-switcher-tree"
  />
</template>
<script setup lang="ts">
import { ref, h, watch } from 'vue'
import { type TreeOption, type TreeDropInfo, NIcon, NButton, useDialog, NInput, useMessage, TreeOverrideNodeClickBehavior } from 'naive-ui'
import {
  BookOutline as BookIcon,
  DocumentTextOutline,
  FolderOpenOutline,
  Add,
  ChevronForward,
  ChevronDownOutline,
  Pencil,
  TrashOutline
} from '@vicons/ionicons5'

// 示例节点数据结构
interface TreeNodeData {
  key: string | number
  parentKey: string | number
  groupId: string | number
  type: string
  label?: string
  heading?: string
  content?: string
  isLoaded?:boolean
  children?: TreeNodeData[]
  pids?: Array<string | number>
}

const props = defineProps<{
  nodes: TreeNodeData[]
  handleLoadChildren: (node: TreeNodeData) => Promise<void>
  updateNodeSort: (nodes: TreeOption[] | undefined, parentKey: string | number, book_id: string | number | undefined) => Promise<void>
  select: (node: TreeNodeData) => Promise<void>
  addNode: (node: TreeNodeData) => Promise<string>
  deleteNode: (node: TreeNodeData) => Promise<boolean>
  updateNode: (node: TreeNodeData) => Promise<void>
}>()
const message = useMessage()
const dialog = useDialog()
// 在组件内部定义响应式变量
const inputValue = ref('')
const localNodes = ref<TreeNodeData[]>(props.nodes)
// 管理每个节点的输入值
const nodeMap = ref<Record<string | number, TreeNodeData>>({})
const handleLoadChildren = props.handleLoadChildren

// 同步外部变化
watch(
  () => props.nodes,
  (v) => {
    localNodes.value = v ?? []
    console.log("同步外部变化", localNodes.value);
    if (!isUpBook(localNodes.value, dataRef.value)) {
      dataRef.value = generateTreeData(localNodes.value, "", undefined, "同步外部变化") ?? []
    }
    
  },
  { deep: true }
)

//判断book是否变化
function isUpBook(def: TreeNodeData[], data: TreeOption[]): boolean {
  // 如果两个数组长度不同，直接返回false
  if (def.length !== data.length) {
    return false;
  }
  
  // 创建映射以便快速查找
  const defMap = new Map();
  const dataMap = new Map();
  
  // 填充映射表
  def.forEach(node => defMap.set(node.key, node));
  data.forEach(node => dataMap.set(node.key, node));
  
  // 检查每个key是否存在且label匹配
  for (const [key, defNode] of defMap) {
    const dataNode = dataMap.get(key);
    
    if (!dataNode || defNode.label !== dataNode.label) {
      return false;
    }
  }
  return true;
}

function renderSwitcherIconWithExpaned({ expanded }: { expanded: boolean }) {
    return h(NIcon, null, { default: () => h(expanded ? ChevronDownOutline : ChevronForward) })
}


// 用来生成数据
function generateTreeData(nodes: TreeNodeData[], _parentKey: string | number = '', def: TreeOption[] | undefined, _desc: string): TreeOption[] | undefined {  
  if (!nodes || nodes.length == 0) {
    return def;
  }
  let list = [];
  for (let i = 0; i < nodes.length; i++) {
    let node = nodes[i];
    list.push(
      generateData(node, def)
    )
  }
  return list;
}

function generateData(node: TreeNodeData, def: TreeOption[] | undefined) {
  nodeMap.value[node.key] = node
  if (node.type === 'moment') {
    return {
      label: node.label,
      key: node.key,
      isLeaf: true,
      type: node.type,
      parentKey: node.parentKey,
      groupId: node.groupId,
      prefix: () =>
        h(NIcon, null, {
          default: () => h(DocumentTextOutline)
        }),
    }
  } else {
    return {
      label: node.label,
      key: node.key,
      isLeaf: false,
      type: node.type,
      parentKey: node.parentKey,
      groupId: node.groupId,
      prefix: () =>
        h(NIcon, null, {
          default: () => h(node.type == "book" ? BookIcon : node.type == "directory" ? FolderOpenOutline : DocumentTextOutline)
        }),
      children: node.children ? generateTreeData(node.children, node.key, def === undefined ? undefined : [], "跟随父级") : def === undefined ? undefined : [],
    }
  }

}

function renderSuffix({ option }: { option: TreeOption }) {
  let node = option;
  let list = [h(
        NButton,
        { text: true, 
          type: 'primary',
          onClick: (e: Event) => {
            e.stopPropagation()
            inputValue.value = node.label ?? "";
            dialog.warning({
            title: '修改名字',
            closable: false,
            showIcon: false,
            content: () => h(NInput, {
              value: inputValue.value,
              onUpdateValue: (value: string) => {
                inputValue.value = value
              },
              placeholder: '请输入内容'
            }, {
              default: () => h(BookIcon)
            }),
            action: () => h(
              NButton,
              { text: true, 
                type: 'primary',
                onClick: (e: Event) => {
                  dialog.destroyAll()
                  node.label = inputValue.value;
                  if (node.key) {
                    handleUpdateClick(node.key, inputValue.value ?? "", e)
                  }
                }
              },
              { default: () => "保存" }
            )
          })
        }
        },
        { default: () => 
          h(NIcon, {
            style:{marginLeft: '5px'}
          }, {
            default: () => h(Pencil)
          })
        }
      ),h(
        NButton,
        { text: true, 
          type: 'primary',
          onClick: (e: Event) => {
            e.stopPropagation()
            dialog.warning({
              title: '警告',
              content: '是否删除？',
              positiveText: '确定',
              negativeText: '取消',
              bordered: false,
              showIcon: false,
              negativeButtonProps: { text: true },
              positiveButtonProps: { text: true },
              draggable: true,
              onPositiveClick: async () => {
                if (node.key) {
                  let data = nodeMap.value[node.key];
                  if (data) {
                    if (await props.deleteNode(data)) {
                      dataRef.value = removeNodeByKey(dataRef.value, node.key)
                      message.success('成功')
                    }
                  } else {
                    message.error("更新数据失败！")
                  }
                }
              },
              onNegativeClick: () => {
                
              }
            })
          }
        },
        { default: () => 
          h(NIcon, {
            style:{marginLeft: '5px'}
          }, {
            default: () => h(TrashOutline)
          })
        }
      )];
  
  if (node.type != "moment") {
    list.unshift(h(
        NButton,
        { text: true, 
          type: 'primary',
          onClick: (e: Event) => {
            e.stopPropagation()
            inputValue.value = "";
            dialog.warning({
            title: '添加',
            closable: false,
            showIcon: false,
            content: () => h(NInput, {
              value: inputValue.value,
              onUpdateValue: (value: string) => {
                inputValue.value = value
              },
              placeholder: '请输入内容'
            }, {
              default: () => h(BookIcon)
            }),
            action: () => h(
              NButton,
              { text: true, 
                type: 'primary',
                onClick: (e: Event) => {
                  dialog.destroyAll()
                  if (node.key) {
                    handleAddClick(nodeMap.value[node.key], inputValue.value, e)
                  }
                }
              },
              { default: () => "保存" }
            )
          })}
        },
        { default: () => 
          h(NIcon, {
            style:{marginLeft: '5px'}
          }, {
            default: () => h(Add)
          })
        }
      ))
  }
  return list;
}

async function handleAddClick(node: TreeNodeData, title: string, e: Event) {
  e.stopPropagation()
  let addNode = {
    key: "-1",
    parentKey: node.key,
    groupId: node.groupId,
    label: title,
    type: 'directory'
  };
  let id = await props.addNode(addNode)
  console.log("新增id ", id)
  if (id === "-1") {
    message.error("添加失败！")
  } else {
    addNode.key = id;
    nodeMap.value[id] = addNode;
    addNodeToParent(dataRef.value, generateData({
      key: id,
      parentKey: node.key,
      groupId: node.groupId,
      label: title,
      type: 'directory',
    }, []), node.key)
  }

}

async function handleUpdateClick(key: string | number, title: string, e: Event) {
  e.stopPropagation()
  let node = nodeMap.value[key];
  console.log("更新", node);
  
  if (node) {
    node.label = title;
    await props.updateNode(node);
  } else {
    message.error("更新数据失败！")
  }
}

const dataRef = ref<TreeOption[]>([])  // 传入的初始数据
const checkedKeysRef = ref<string[]>([])
const expandedKeysRef = ref<string[]>([])
// 定义暴露给父组件的接口
export interface TreeExposed {
  addNode: (node: TreeOption, key: string|number) => void
  upNode: (key: string|number, label: string) => void
}
// 暴露方法
defineExpose<TreeExposed>({
  addNode,
  upNode
})
//加载子集
function handleLoad(node: TreeOption) {
  console.log("\\\\\\\\\\\\", node)
  // 判断如果节点没有类型或没有子节点，直接返回
  if (node.type !== "book" && !node.children) {
    return new Promise<void>((resolve) => {
      node.children = []; // 设置为空数组，表示没有子节点
      resolve(); // 结束加载
    });
  }
  if (node.key) {
    let n = nodeMap.value[node.key];
    // 如果节点已经加载过，避免再次加载
    if (n.isLoaded) {
      return new Promise<void>((resolve) => {
        node.children = []; // 设置为空数组，表示没有子节点
        resolve(); // 结束加载
      });
    }
    handleLoadChildren(n)
    return new Promise((resolve) => {
        const unwatch = watch(
          () => n.isLoaded,
          (loaded) => {
            if (loaded) {
              unwatch();
              resolve(n);
              node.children = n.children && n.children.length > 0 ? generateTreeData(n.children, node.key, [], "异步") : [];
              console.log("node1 ", node);
            }
          }
        );
    })
  }
}

function addNode(node: any, key: string|number) {
  nodeMap.value[node.key] = node;
  if (addNodeToParent(dataRef.value, generateData(node, undefined), key)) {
    dataRef.value = [...dataRef.value];
  }
  console.log("========== ",dataRef.value);
  
}

function upNode(key: string|number, label: string) {
  let node = nodeMap.value[key];
  node.label = label
  if (upNodeLabel(dataRef.value, key, label)) {
    
  }
}


const override: TreeOverrideNodeClickBehavior = ({ option }) => {
  if (option.key) {
    props.select(nodeMap.value[option.key])
    // console.log(option.type)
    // if (option.type == 'book') {
    //   let n = nodeMap.value[option.key];
    //    n.isLoaded = false;
    //   handleLoadChildren(n)
    //   new Promise((resolve) => {
    //       const unwatch = watch(
    //         () => n.isLoaded,
    //         (loaded) => {
    //           if (loaded) {
    //             unwatch();
    //             resolve(n);
    //             option.children = n.children && n.children.length > 0 ? generateTreeData(n.children, option.key, [], "异步") : [];
    //             console.log("option", option);
                
    //           }
    //         }
    //       );
    //   })
    // }
  }
  return 'default'
}


// 更新展开的节点
function handleExpandedKeysChange(expandedKeys: string[]) {
  expandedKeysRef.value = expandedKeys
}


// 处理拖拽事件
function handleDrop({ node, dragNode, dropPosition }: TreeDropInfo) {
  if (dragNode.key == "1") {
    message.warning("默认不要拖动！")
    return;
  }
  if (dropPosition === 'before') {
    if (node.key == "1") {
      message.warning("不能放到默认前！")
      return;
    }
  }
  const [dragNodeSiblings, dragNodeIndex] = findSiblingsAndIndex(dragNode, dataRef.value)
  if (dragNodeSiblings === null || dragNodeIndex === null) return

  dragNodeSiblings.splice(dragNodeIndex, 1) // 移除拖动的节点
  console.log("node ---- ", node);
  console.log("dragNode ---- ", dragNode);
  console.log("dropPosition ---- ", dropPosition);

  // 根据拖拽位置处理
  if (dropPosition === 'inside') {
    if (node.children) {
      node.children.unshift(dragNode) // 放入目标节点的子节点
    } else {
      node.children = [dragNode] // 如果没有子节点则新建
    }
    if (dragNode.key && node.key) {
      let dbNode = nodeMap.value[node.key];
      nodeMap.value[dragNode.key].parentKey = dbNode.key;
      nodeMap.value[dragNode.key].groupId = dbNode.groupId;
    }
    props.updateNodeSort(node.children, node.key? node.key : "".toString(), node.key ? (nodeMap.value[node.key].groupId) : undefined)
  } else if (dropPosition === 'before') {
    const [nodeSiblings, nodeIndex] = findSiblingsAndIndex(node, dataRef.value)
    if (nodeSiblings === null || nodeIndex === null) return
    nodeSiblings.splice(nodeIndex, 0, dragNode) // 在目标节点前插入

    if (dragNode.key && node.key) {
      let dbNode = nodeMap.value[node.key];
      if (nodeMap.value[dragNode.key].parentKey != dbNode.parentKey) {
        nodeMap.value[dragNode.key].parentKey = dbNode.parentKey;
        nodeMap.value[dragNode.key].groupId = dbNode.groupId;
      }
    }
    props.updateNodeSort(nodeSiblings, node.key ? nodeMap.value[node.key].parentKey:"", node.key ? (nodeMap.value[node.key].groupId) : undefined )
  } else if (dropPosition === 'after') {
    const [nodeSiblings, nodeIndex] = findSiblingsAndIndex(node, dataRef.value)
    if (nodeSiblings === null || nodeIndex === null) return
    nodeSiblings.splice(nodeIndex + 1, 0, dragNode) // 在目标节点后插入

    if (dragNode.key && node.key) {
      let dbNode = nodeMap.value[node.key];
      if (nodeMap.value[dragNode.key].parentKey != dbNode.parentKey) {
        nodeMap.value[dragNode.key].parentKey = dbNode.parentKey;
        nodeMap.value[dragNode.key].groupId = dbNode.groupId;
      }
    }
    props.updateNodeSort(nodeSiblings, node.key ? nodeMap.value[node.key].parentKey:"", node.key ? (nodeMap.value[node.key].groupId) : undefined)
  }
  console.log("--------------", dataRef.value);

  
  dataRef.value = [...dataRef.value] // 更新树数据
}

// 查找兄弟节点及其索引
function findSiblingsAndIndex(node: TreeOption, nodes?: TreeOption[]): [TreeOption[], number] | [null, null] {
  if (!nodes) return [null, null]
  for (let i = 0; i < nodes.length; ++i) {
    const siblingNode = nodes[i]
    if (siblingNode.key === node.key) return [nodes, i]
    const [siblings, index] = findSiblingsAndIndex(node, siblingNode.children)
    if (siblings && index !== null) return [siblings, index]
  }
  return [null, null]
}

//删除指定key
function removeNodeByKey(nodes: TreeOption[], targetKey: string | number): TreeOption[] {
  return nodes
    .filter(node => node.key !== targetKey)
    .map(node => ({
      ...node,
      children: node.children ? removeNodeByKey(node.children, targetKey) : undefined
    }));
}

/**
 * 将节点添加到指定key的子集中
 * @param nodes 节点数组
 * @param node 要添加的节点
 * @param targetKey 目标父节点的key
 * @returns 是否成功添加
 */
function addNodeToParent(
  nodes: TreeOption[], 
  node: TreeOption, 
  targetKey: string | number
): boolean {
  // 如果要添加的节点就是目标节点本身，直接添加到根层级
  if (node.key === targetKey) {
    nodes.unshift(node);
    return true;
  }
  
  // 遍历节点树查找目标父节点
  for (const currentNode of nodes) {
    // 如果当前节点就是目标父节点
    if (currentNode.key === targetKey) {
      // 确保children数组存在
      if (!currentNode.children) {
        currentNode.children = [];
      }
      // 设置节点的parentKey
      node.parentKey = targetKey;
      // 添加到子集
      currentNode.children.unshift(node);
      return true;
    }
    
    // 如果当前节点有子节点，递归搜索
    if (currentNode.children && currentNode.children.length > 0) {
      const found = addNodeToParent(currentNode.children, node, targetKey);
      if (found) {
        return true;
      }
    }
  }
  
  return false;
}


/**
 * 修改指定key的label
 * @param nodes 节点数组
 * @param targetKey 目标点的key
 * @param label 修改的标题
 * @returns 是否成功添加
 */
function upNodeLabel(
  nodes: TreeOption[], 
  targetKey: string | number,
  label: string
): boolean {
  
  // 遍历节点树查找目标父节点
  for (const currentNode of nodes) {
    // 如果当前节点就是目标父节点
    if (currentNode.key === targetKey) {
      // 确保children数组存在
      if (!currentNode.children) {
        currentNode.children = [];
      }
      //修改label
      currentNode.label = label;
      return true;
    }
    
    // 如果当前节点有子节点，递归搜索
    if (currentNode.children && currentNode.children.length > 0) {
      const found = upNodeLabel(currentNode.children, targetKey, label);
      if (found) {
        return true;
      }
    }
  }
  
  return false;
}



</script>


<style scoped>
.right-switcher-tree {
  --n-node-indent: 0px;
}

/* 移动展开/折叠指示器到右侧 */
.right-switcher-tree :deep(.n-tree-node) {
  position: relative;
  padding-right: 24px;
  padding-top: 5px; 
  padding-bottom: 5px;
}

.right-switcher-tree :deep(.n-tree-node-switcher) {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  margin-left: 0;
}

.right-switcher-tree :deep(.n-tree-node-content) {
  padding-left: 12px;
  padding-right: 2px;
}

.right-switcher-tree :deep(.n-tree-node-content__prefix) {
  margin-right: px;
}

/* 确保树线正确显示 */
.right-switcher-tree :deep(.n-tree-node--block-line .n-tree-node-line) {
  left: auto;
  right: 12px;
}

.right-switcher-tree :deep(.n-tree-node--block-line .n-tree-node-indent) {
  display: none;
}
</style>